package tt.dz.biz.dao.channel;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;
import tt.dz.biz.dao.BaseDAO;
import tt.dz.biz.dao.merch.ChangeDayDAOImp;
import tt.dz.common.DateUtil;
import tt.dz.common.LogUtil;
import tt.dz.vo.ChannelCheckResult;
import tt.dz.vo.ChannelCheckVO;
import tt.dz.vo.ChannelCheckdetailVO;

public abstract class ChannelCheckDaoImp
  extends BaseDAO
{
  @Resource(name="changeDayDAO")
  ChangeDayDAOImp changeDayDao;
  private static final String INSERT_CHANNEL_CHECK = "insert into ms_channel_check(channel_code,accounting_date,number,amount,result_state,adjust_state,check_time)  values(:channelCode,:accountingDate,:number,:amount,:resultState,:adjustState,:checkTime )";
  private static final String INSERT_CHANNEL_CHECKDETAIL = "insert into ms_channel_checkdetail(channel_code,accounting_code,trade_no,tran_date,tran_amount,chnl_state,plat_pay_time,plat_pay_state,plat_pay_type,check_state,check_result,mannul_flag)  values(:channelCode,:accountingCode,:tradeNo,:tranDate,:tranAmount,:chnlState,:platPayTime,:platPayState,:platPayType,:checkState,:checkResult,:mannulFlag )";
  protected static final String CHANNEL_CHECK_SQL = "select a.channel_code,a.accounting_date,count(1) account_num,sum(a.payment_amount) sum_payment_amount  from ms_tran_info a   where  a.channel_code=:channelCode and (check_account_sate is null or check_account_sate='00')  group by a.channel_code,a.accounting_date";
  protected static final String UPDATE_TRAN_INFO = "update ms_tran_info set check_account_sate=:checkAccountSate where trade_no=:tradeNo ";
  protected Date accountingDate;
  
  public void ChannelCheck()
    throws Exception
  {
    this.accountingDate = this.changeDayDao.queryAccountingDateForChangeDay();
    ChannelCheckResult channelCheckResult = check();
    if ((channelCheckResult != null) && (channelCheckResult.getChannelCheckVo() != null))
    {
      save("insert into ms_channel_check(channel_code,accounting_date,number,amount,result_state,adjust_state,check_time)  values(:channelCode,:accountingDate,:number,:amount,:resultState,:adjustState,:checkTime )", channelCheckResult.getChannelCheckVo());
      batchSave("insert into ms_channel_checkdetail(channel_code,accounting_code,trade_no,tran_date,tran_amount,chnl_state,plat_pay_time,plat_pay_state,plat_pay_type,check_state,check_result,mannul_flag)  values(:channelCode,:accountingCode,:tradeNo,:tranDate,:tranAmount,:chnlState,:platPayTime,:platPayState,:platPayType,:checkState,:checkResult,:mannulFlag )", channelCheckResult.getChannelCheckdetailList());
    }
    else
    {
      LogUtil.info("对账实体为空，已经对账或者对账异常。");
    }
  }
  
  private ChannelCheckResult check()
    throws Exception
  {
    this.accountingDate = this.changeDayDao.queryAccountingDateForChangeDay();
    LogUtil.info("渠道对账开始，会计日期：" + DateUtil.getStringByYMD(this.accountingDate) + "渠道编号：" + getChannelNo());
    ChannelCheckResult channelCheckResult = new ChannelCheckResult();
    MapSqlParameterSource parameters = new MapSqlParameterSource();
    parameters.addValue("channelCode", getChannelNo());
    Map<String, Object> channelCheckMap = findInstanceBysql("select a.channel_code,a.accounting_date,count(1) account_num,sum(a.payment_amount) sum_payment_amount  from ms_tran_info a   where  a.channel_code=:channelCode and (check_account_sate is null or check_account_sate='00')  group by a.channel_code,a.accounting_date", parameters);
    if (CollectionUtils.isEmpty(channelCheckMap))
    {
      LogUtil.info("在交易流水表查询不到相关信息，会计日期：" + DateUtil.getStringByYMD(this.accountingDate) + "渠道编号：" + getChannelNo());
      return null;
    }
    ChannelCheckVO channelCheckVo = new ChannelCheckVO();
    channelCheckVo.setChannelCode((String)channelCheckMap.get("channelCode"));
    channelCheckVo.setAccountingDate(this.accountingDate);
    channelCheckVo.setAmount((BigDecimal)channelCheckMap.get("sumPaymentAmount"));
    Long accountNum = (Long)channelCheckMap.get("accountNum");
    channelCheckVo.setNumber(Integer.valueOf(accountNum != null ? accountNum.intValue() : 0));
    List<ChannelCheckdetailVO> channelCheckdetailList = getChannelCheckDetailList();
    if (CollectionUtils.isEmpty(channelCheckdetailList))
    {
      LogUtil.debug("渠道编号：" + getChannelNo() + "平账");
      channelCheckVo.setResultState(Integer.valueOf(1));
    }
    else
    {
      LogUtil.debug("渠道编号：" + getChannelNo() + "不平账，不平账记录数:" + channelCheckdetailList.size());
      channelCheckVo.setResultState(Integer.valueOf(2));
    }
    channelCheckVo.setAdjustState(Integer.valueOf(0));
    channelCheckVo.setCheckTime(new Date());
    channelCheckResult.setChannelCheckVo(channelCheckVo);
    channelCheckResult.setChannelCheckdetailList(channelCheckdetailList);
    return channelCheckResult;
  }
  
  protected abstract List<ChannelCheckdetailVO> getChannelCheckDetailList()
    throws Exception;
  
  protected abstract String getChannelNo();
  
  protected List<Map<String, Object>> findListBySql(String sql, MapSqlParameterSource parameters)
  {
    return queryForList(sql, parameters);
  }
  
  protected Map<String, Object> findInstanceBysql(String sql, MapSqlParameterSource parameters)
  {
    List<Map<String, Object>> tmpList = findListBySql(sql, parameters);
    return (tmpList != null) && (tmpList.size() > 0) ? (Map)tmpList.get(0) : null;
  }
  
  protected int updateBySql(String sql, Map<String, ?> params)
  {
    MapSqlParameterSource paramMap = new MapSqlParameterSource(params);
    return this.jdbcTemplate.update(sql, paramMap);
  }
  
  protected int[] batchupdateBySql(String sql, Map<String, ?>[] params)
  {
    return this.jdbcTemplate.batchUpdate(sql, params);
  }
}
